package com.atguigu.tingshu.album.service.impl;

import com.atguigu.tingshu.album.mapper.AlbumAttributeValueMapper;
import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.mapper.AlbumStatMapper;
import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.common.cache.TsCache;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.rabbit.constant.MqConst;
import com.atguigu.tingshu.common.rabbit.service.RabbitService;
import com.atguigu.tingshu.model.album.AlbumAttributeValue;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.AlbumStat;
import com.atguigu.tingshu.query.album.AlbumInfoQuery;
import com.atguigu.tingshu.vo.album.AlbumAttributeValueVo;
import com.atguigu.tingshu.vo.album.AlbumInfoVo;
import com.atguigu.tingshu.vo.album.AlbumListVo;
import com.atguigu.tingshu.vo.album.AlbumStatVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.Nullable;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Random;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class AlbumInfoServiceImpl extends ServiceImpl<AlbumInfoMapper, AlbumInfo> implements AlbumInfoService {

    @Autowired
    private AlbumInfoMapper albumInfoMapper;

    @Autowired
    private AlbumStatMapper albumStatMapper;

    @Autowired
    private AlbumAttributeValueMapper albumAttributeValueMapper;

    @Autowired
    private RabbitService rabbitService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RedissonClient redissonClient;

    /**
     * 新增专辑
     *
     * @param albumInfoVo
     */
    // 使用Transaction注解确保方法执行过程中发生异常时回滚事务
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveAlbumInfo(AlbumInfoVo albumInfoVo, Long userId) {

        // 创建AlbumInfo对象并从传入的Vo中复制属性
        AlbumInfo albumInfo = new AlbumInfo();
        BeanUtils.copyProperties(albumInfoVo, albumInfo);
        // 设置专辑的用户ID
        albumInfo.setUserId(userId);
        // 如果专辑不是免费类型，则设置默认的免费试听曲目数量
        if (!albumInfo.getPayType().equals(SystemConstant.ALBUM_PAY_TYPE_FREE)) {
            albumInfo.setTracksForFree(5);
        }
        // 设置专辑状态为已通过审核
        albumInfo.setStatus(SystemConstant.ALBUM_STATUS_PASS);
        // 插入专辑信息到数据库
        albumInfoMapper.insert(albumInfo);

        // 获取专辑属性值列表，如果不为空，则遍历并插入到数据库
        List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();
        if (!CollectionUtils.isEmpty(albumAttributeValueVoList)) {
            for (AlbumAttributeValueVo albumAttributeValueVo : albumAttributeValueVoList) {
                AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
                BeanUtils.copyProperties(albumAttributeValueVo, albumAttributeValue);
                // 设置专辑ID
                albumAttributeValue.setAlbumId(albumInfo.getId());
                // 插入专辑属性值到数据库
                albumAttributeValueMapper.insert(albumAttributeValue);
            }
        }
        // 保存专辑的播放统计信息
        saveAlbumStat(albumInfo.getId(), SystemConstant.ALBUM_STAT_PLAY);
        // 保存专辑的订阅统计信息
        saveAlbumStat(albumInfo.getId(), SystemConstant.ALBUM_STAT_SUBSCRIBE);
        // 保存专辑的购买统计信息
        saveAlbumStat(albumInfo.getId(), SystemConstant.ALBUM_STAT_BROWSE);
        // 保存专辑的评论统计信息
        saveAlbumStat(albumInfo.getId(), SystemConstant.ALBUM_STAT_COMMENT);

        //判断当前专辑是否上架下架
        if ("1".equals(albumInfo.getIsOpen())) {
            //发送消息到消息队列
            rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM, MqConst.ROUTING_ALBUM_UPPER, albumInfo.getId());

            //	将新增的商品SKUID存入布隆过滤器
            //	获取布隆过滤器，将新增skuID存入布隆过滤器
            redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER).add(albumInfo.getId());
        }
    }

    /**
     * 保存专辑的统计信息
     *
     * @param id            专辑ID
     * @param albumStatPlay 统计类型
     */
    private void saveAlbumStat(Long id, String statType) {
        // 创建AlbumStat对象并设置属性
        AlbumStat albumStat = new AlbumStat();
        albumStat.setAlbumId(id);
        albumStat.setStatType(statType);
        // 随机生成统计数值
        albumStat.setStatNum(new Random().nextInt(100000));
        // 插入统计信息到数据库
        albumStatMapper.insert(albumStat);
    }

    @Override
    public void pageList(Page<AlbumListVo> albumListVoPage, AlbumInfoQuery albumInfoQuery) {
        albumListVoPage = albumInfoMapper.pageList(albumListVoPage, albumInfoQuery);
    }

    /**
     * 删除专辑
     *
     * @param id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeAlbumInfo(Long id) {
        //删除专辑信息表
        albumInfoMapper.deleteById(id);
        //删除专辑属性关系表
        LambdaQueryWrapper<AlbumAttributeValue> albumAttributeValueLambdaQueryWrapper = new LambdaQueryWrapper<>();
        albumAttributeValueLambdaQueryWrapper.eq(AlbumAttributeValue::getAlbumId, id);
        albumAttributeValueMapper.delete(albumAttributeValueLambdaQueryWrapper);
        //删除专辑统计表
        LambdaQueryWrapper<AlbumStat> albumStatLambdaQueryWrapper = new LambdaQueryWrapper<>();
        albumStatLambdaQueryWrapper.eq(AlbumStat::getAlbumId, id);
        albumStatMapper.delete(albumStatLambdaQueryWrapper);
        rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM, MqConst.ROUTING_ALBUM_LOWER, id);
    }


    /**
     * 根据专辑ID获取专辑信息
     *
     * @param id 专辑ID
     * @return 专辑信息对象
     */
    @TsCache(prefix = RedisConstant.ALBUM_INFO_PREFIX)
    @Override
    public AlbumInfo getAlbumInfo(Long id) {
        return getAlbumInfoFromDB(id);
    }

    /**
     * 根据专辑id获取专辑信息
     *
     * @param id
     * @return
     */
    @Nullable
    private AlbumInfo getAlbumInfoFromDB(Long id) {
        // 根据ID查询专辑信息
        AlbumInfo albumInfo = albumInfoMapper.selectById(id);

        // 如果专辑信息不为空
        if (albumInfo != null) {
            // 创建查询条件，用于查询专辑属性值
            LambdaQueryWrapper<AlbumAttributeValue> albumAttributeValueLambdaQueryWrapper = new LambdaQueryWrapper<>();
            // 设置查询条件为专辑ID等于传入的ID
            albumAttributeValueLambdaQueryWrapper.eq(AlbumAttributeValue::getAlbumId, id);

            // 根据查询条件查询专辑属性值列表
            List<AlbumAttributeValue> albumAttributeValueList = albumAttributeValueMapper.selectList(albumAttributeValueLambdaQueryWrapper);

            // 将查询到的专辑属性值列表设置到专辑信息对象中
            albumInfo.setAlbumAttributeValueVoList(albumAttributeValueList);
        }

        // 返回专辑信息对象
        return albumInfo;
    }

    /**
     * 根据ID修改专辑信息
     *
     * @param id          专辑ID
     * @param albumInfoVo 包含修改后的专辑信息的对象
     */
    @Override
    public void updateAlbumInfo(Long id, AlbumInfoVo albumInfoVo) {
        // 根据ID获取当前的专辑信息
        AlbumInfo albumInfo = this.getById(id);

        // 将传入的专辑信息对象中的属性复制到获取到的专辑信息对象中
        BeanUtils.copyProperties(albumInfoVo, albumInfo);

        // 更新专辑信息
        this.updateById(albumInfo);

        // 获取传入的专辑属性值列表
        List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();

        // 如果专辑属性值列表不为空
        if (!CollectionUtils.isEmpty(albumAttributeValueVoList)) {
            // 创建查询条件，用于删除旧的专辑属性值
            LambdaQueryWrapper<AlbumAttributeValue> albumAttributeValueLambdaQueryWrapper = new LambdaQueryWrapper<>();
            albumAttributeValueLambdaQueryWrapper.eq(AlbumAttributeValue::getAlbumId, id);

            // 根据查询条件删除旧的专辑属性值
            albumAttributeValueMapper.delete(albumAttributeValueLambdaQueryWrapper);

            // 遍历新的专辑属性值列表
            for (AlbumAttributeValueVo albumAttributeValueVo : albumAttributeValueVoList) {
                // 创建新的专辑属性值对象
                AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();

                // 将传入的专辑属性值对象中的属性复制到新的专辑属性值对象中
                BeanUtils.copyProperties(albumAttributeValueVo, albumAttributeValue);

                // 设置专辑ID
                albumAttributeValue.setAlbumId(id);

                // 插入新的专辑属性值
                albumAttributeValueMapper.insert(albumAttributeValue);
            }
        }
        //判断专辑上架下架
        if ("1".equals(albumInfo.getIsOpen())) {
            //上架
            rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM, MqConst.ROUTING_ALBUM_UPPER, id);
            //	将新增的商品SKUID存入布隆过滤器
            //	获取布隆过滤器，将新增skuID存入布隆过滤器
            redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER).add(albumInfo.getId());
        } else {
            rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM, MqConst.ROUTING_ALBUM_LOWER, id);
        }
    }

    /**
     * 获取当前用户全部专辑列表
     * 本函数通过查询数据库中与用户ID关联的所有专辑信息，并按照专辑ID降序排列，最后返回最多50条专辑信息
     *
     * @param userId 用户ID，用于查询该用户下的所有专辑
     * @return 包含用户所有专辑信息的列表
     */
    @Override
    public List<AlbumInfo> findUserAllAlbumList(Long userId) {
        // 创建查询条件构造器
        LambdaQueryWrapper<AlbumInfo> albumInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 设置查询条件为用户ID等于传入的参数userId，以获取指定用户的所有专辑
        albumInfoLambdaQueryWrapper.eq(AlbumInfo::getUserId, userId);
        // 设置查询结果按照专辑ID降序排列，并限制查询结果数量为最多50条
        albumInfoLambdaQueryWrapper.orderByDesc(AlbumInfo::getId).last(" limit 50 ");
        // 执行查询并返回结果列表
        List<AlbumInfo> albumInfoList = albumInfoMapper.selectList(albumInfoLambdaQueryWrapper);
        return albumInfoList;
    }

    /**
     * 根据专辑id获取专辑属性信息
     *
     * @param albumId
     * @return
     */
    @Override
    public List<AlbumAttributeValue> getAlbumAttributeValue(Long albumId) {
        LambdaQueryWrapper<AlbumAttributeValue> albumAttributeValueLambdaQueryWrapper = new LambdaQueryWrapper<>();
        albumAttributeValueLambdaQueryWrapper.eq(AlbumAttributeValue::getAlbumId, albumId);
        List<AlbumAttributeValue> albumAttributeValueList = albumAttributeValueMapper.selectList(albumAttributeValueLambdaQueryWrapper);
        return albumAttributeValueList;
    }

    /**
     * 根据专辑id获取专辑统计信息
     *
     * @param albumId
     * @return
     */
    @TsCache(prefix = "stat:info:")
    @Override
    public AlbumStatVo getStat(Long albumId) {
        AlbumStatVo stat = albumInfoMapper.getStat(albumId);
        return stat;
    }
}
